home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Finder ProgressBar 1.1 / Finder ProgressBar.h < prev    next >
Text File  |  1994-04-28  |  6KB  |  111 lines

  1. /*****************************************************************************************************
  2. *                                                                                                    *
  3. * Finder ProgressBar.h - Copyright 1993 - 1994 Chris Larson, All rights reserved                     *
  4. *                                              (cklarson@engr.ucdavis.edu)                           *
  5. *                                                                                                    *
  6. * This is the header file for a CDEF which mimics the progress bar used by the Finder. This file and *
  7. * compiled derivatives may be freely used within any freeware/shareware/postcardware/beerware/… as   *
  8. * long as you mention my name in your credits. Neither this source nor its compiled derivatives are  *
  9. * in the public domain and may not be use in any form in public domain software. Neither this source *
  10. * nor its compiled derivatives may be used in any form in a commercial product without the expressed,*
  11. * written consent of the author (me).                                                                *
  12. *                                                                                                    *
  13. * Version 1.1 -- April 28, 1994.                                                                     *
  14. *                                                                                                    *
  15. *****************************************************************************************************/
  16.  
  17. // Constants
  18.  
  19. #define kNoColorQD    0x4000    // If this bit in ROM85 is set, color QD is not available.
  20.  
  21. #define    cBlack        { 0x0000, 0x0000, 0x0000 }
  22. #define cWhite        { 0xFFFF, 0xFFFF, 0xFFFF }
  23. #define cGray        { 0x4444, 0x4444, 0x4444 }
  24. #define cBlue        { 0xCCCC, 0xCCCC, 0xFFFF }
  25.  
  26. // Inline Functions
  27.  
  28. // ----------
  29. // NOTE: These two routines are not intended as a general replacement of the SetUpA4() and
  30. //         RestoreA4() functions. THEY ARE NOT GENERAL; THEY WILL NOT WORK ANYWHERE BUT HERE.
  31. // ----------
  32.  
  33. void MySetUpA4(void)
  34.     = {
  35.         0x2F0C,   //    move.l    a4,-(a7)    ; Push a4
  36.         0x2848      //    movea.l    a0,a4        ; Load address of code resource into a4
  37.       };
  38.  
  39. void MyRestoreA4(void)
  40.     = {
  41.         0x285F    //    move.l    (a7)+,a4    ; Pop a4
  42.       };
  43.  
  44. // ----------
  45. // Notes about CalculateBarBoundry():
  46. //
  47. // This function calculates the location of the edge of the progress bar given the current
  48. // control settings. The calculation corresponds to the following equation:
  49. //
  50. //                           ( boxRight - boxLeft ) * ( controlValue - controlMinimum )
  51. //        result = boxLeft + ----------------------------------------------------------
  52. //                                      ( controlMaximum - controlMinimum )
  53. //
  54. // Correct operation of this function requires the following conditions:
  55. //        (1)    controlMax >= controlValue >= controlMinimum
  56. //        (2)    boxRight >= boxLeft
  57. //
  58. // Both of these sould be met in all normal curcumstances (i.e. control maxima should always
  59. // be greater than control minima; control values should always be between the control's maximum
  60. // and minimum; and the left coordinate of the control's rectangle should be less than the right
  61. // edge (otherwise the rectangle is empty). Imposing these conditions allows me to calculate
  62. // the correct answer no matter what values these variables contain. For example, controlMax and
  63. // controlMin are both short integers (16 bits) limited to the range [-32768,32767]. Without the
  64. // restriction that controlMin <= controlMax, the difference ( controlMax - controlMin ) could
  65. // be anywhere within the range [-65535,65535] which is a 17 bit signed quantity. With the
  66. // restriction the difference is limited to the range [0,65535] which fits into an unsigned
  67. // 16 bit word. Big deal; registers are 32 bits. Why not just use 32 bit signed quantities?
  68. // Well, then when I computed the product in the numerator I would have to use a quad word (64 bits)
  69. // to store it. The quad word multiplication routines are implemented in software on the 68000
  70. // and require inclusion of a library that is larger than this code resource. I wanted to avoid
  71. // needing this library, if possible, without requiring a 68020. Further, normal use of the control
  72. // obeys all of my conditions anyway so I felt it was well worthwhile.
  73. //
  74. // As it stands, the algorithm computes the two differences in the numerator, storing each into a
  75. // 16 bit unsigned word. If the control value and control minimum are the same, there is no progress
  76. // to display, so the left edge is returned (actually it was given in d0 and d0 has not been altered
  77. // so I only have to exit). Otherwise, the two unsigned 16 bit words are multiplied together to
  78. // yield a 32 bit unsigned long word product. The difference in the denominator is now calculated and
  79. // placed into a 16 bit unsigned word. Note that no check is made to see if a divide by zero will
  80. // occur. This is owing to the conditions outlined above: if the max and min are equal (the only
  81. // way to get a zero in the denominator) then the control value must be equal to both. This case
  82. // was detected in the earlier check so I need not repeat it. The division is carried out, resulting
  83. // in a 16 bit unsigned quotient. This quotient is then added to boxLeft to yield the 16 bit
  84. // signed result value.
  85. //
  86. // The routine is coded in inline assembly because I couldn’t get this #@!%ing compiler to recognize
  87. // and use the mulu.w and divu.w instructions properly (it was using the library even though it was
  88. // not strictly necessary).
  89. // ----------
  90.  
  91. #pragma parameter __D0 CalculateBarBoundry(__D0, __D1, __A0)
  92. short CalculateBarBoundry(short boxLeft, short boxRight, ControlPtr theControl)
  93.     = {
  94.         0x9240,            //            sub.w    d0,d1            ; Box width to d1
  95.         0x3268, 0x0014,    //            movea.w    $0014(a0),a1    ; Control minimum to a1
  96.         0x3428, 0x0012,    //            move.w    $0012(a0),d2    ; Control value to d2
  97.         0x9449,            //            sub.w    a1,d2            ; Normalized control setting to d2
  98.         0x670C,            //            beq        @done            ; Value == minimum so we’re done
  99.         0xC2C2,            //            mulu.w    d2,d1            ; ( width * normalized setting ) to d1
  100.         0x3428, 0x0016,    //            move.w    $0016(a0),d2    ; Control maximum to d2
  101.         0x9449,            //            sub.w    a1,d2            ; Control range to d2
  102.         0x82C2,            //            divu.w    d2,d1            ; (width*normalized setting)/range to d1
  103.         0xD041,            //            add.w    d1,d0            ; result to d0
  104.                         // @done:
  105.       };
  106.  
  107. // Function Prototypes
  108.  
  109. pascal long main(short varCode, ControlHandle theControlHandle, short message, long param);
  110. void DrawProgressBar(ControlPtr theControl);
  111.